﻿using CKS2320.Common;
using CKS2320.Common.Model;
using CKS2320.Common.Transfer;
using CKS2320.Common.Utils;
using CKS2320.Domain.DBEntity;
using CKS2320.Repository;
using CKS2320.Repository.Interface;
using CKS2320.Service.Interface;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CKS2320.Service
{
    public class ThicknessDetectionService : IThicknessDetectionService
    {
        public IThicknessDetectionRepository _thicknessDetectionRepository;
        private readonly LogService _logService;
        public ThicknessDetectionService(IThicknessDetectionRepository thicknessDetectionRepository, LogService logService)
        {
            _thicknessDetectionRepository = thicknessDetectionRepository;
            _logService = logService;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <returns></returns>
        public ResultReturn Add(ThicknessDetectionModel tdModel)
        {
            try
            {
                //List<IndicatorToleranceZoneModel> listIndicator = IndicatortolerancezoneJsonLoad();
                ParaShowSetModel parainstance = new ParaShowSetModel();
                _logService.LogOp30("保存参数" + JsonConvert.SerializeObject(tdModel) + "\r\n");
                /*ParaShowSetModel para = */
                parainstance = ParaJsonLoad();
                float? FacedCamber = null;//立面拱曲度
                //float? backScallop2Pitch = null;//背面间距
                //float? backScallop2Diameter = null;//背面直径
                float? backScallop3Pitch = null;
                float? backScallop3Diameter = null;
                //float? frontScallop2Pitch = null;//正面间距
                //float? frontScallop2Diameter = null;//正面直径
                //float? frontScallop3Pitch = null;
                //float? frontScallop3Diameter = null;
                float? maxThickness = null;//最大膜厚
                float? MiniThickness = null;//最小膜厚
                string? FinalJudge = null;//最终判定
                float? FtFs = null;//正面首波到首端距离
                float? FtLs = null;
                float? BtFs = null;
                float? BtLs = null;
                float? FCT1 = null;
                float? FCT2 = null;
                float? FCT3 = null;
                float? FCT4 = null;
                float? FCT5 = null;
                float? FCT6 = null;
                float? FCT7 = null;
                float? BCT1 = null;
                float? BCT2 = null;
                float? BCT3 = null;
                float? BCT4 = null;
                float? BCT5 = null;
                float? BCT6 = null;
                float? BCT7 = null;
                string FSTotalJudge = "NG";
                string fs1 = "FS" + /*para*/parainstance.FS1;
                string fs2 = "FS" + parainstance.FS2;
                string fd1 = "FD" + parainstance.FD1;
                string fd2 = "FD" + parainstance.FD2;
                string bs1 = "BS" + parainstance.BS1;
                string bs2 = "BS" + parainstance.BS2;
                string bd1 = "BD" + parainstance.BD1;
                string bd2 = "BD" + parainstance.BD2;

                if (tdModel._3dscannerResult1 == true
                       && tdModel.FrontThicknessResult1 == true
                       && tdModel.FacadeCurvatureResult == true)
                {
                    tdModel.Result = true;
                }
                else
                {
                    tdModel.Result = false;
                }
                Thicknessdetection TDEntity = new()
                {
                    Id = Guid.NewGuid(),
                    StationCode = tdModel.StationCode,
                    Heart1 = tdModel.Heart1,
                    StartUpLoad = tdModel.StartUpLoad,
                    Heart2 = tdModel.Heart2,
                    EndUpLoad = tdModel.EndUpLoad,
                    PartCode = tdModel.PartCode,
                    _3dscannerStart = tdModel._3dscannerStart,
                    _3dscannerEnd = tdModel._3dscannerEnd,
                    _3dscannerResult = tdModel._3dscannerResult1,
                    TotalLengthResult = tdModel.TotalLengthResult,
                    CrlargeEndDistanceResult = tdModel.CrlargeEndDistanceResult,
                    CrsmallEndDistanceResult = tdModel.CrsmallEndDistanceResult,
                    Crfront1WaveDistanceResult = tdModel.Crfront1WaveDistanceResult,
                    Crfront64WaveDistanceResult = tdModel.Crfront64WaveDistanceResult,
                    BackThicknessResult1 = tdModel.BackThicknessResult1,
                    BackThicknessResult2 = tdModel.BackThicknessResult2,
                    BackThicknessResult3 = tdModel.BackThicknessResult3,
                    BackThicknessResult4 = tdModel.BackThicknessResult4,
                    BackThicknessResult5 = tdModel.BackThicknessResult5,
                    BackThicknessResult6 = tdModel.BackThicknessResult6,
                    BackThicknessResult7 = tdModel.BackThicknessResult7,
                    FrontThicknessResult1 = tdModel.FrontThicknessResult1,
                    FrontThicknessResult2 = tdModel.FrontThicknessResult2,
                    FrontThicknessResult3 = tdModel.FrontThicknessResult3,
                    FrontThicknessResult4 = tdModel.FrontThicknessResult4,
                    FrontThicknessResult5 = tdModel.FrontThicknessResult5,
                    FrontThicknessResult6 = tdModel.FrontThicknessResult6,
                    FrontThicknessResult7 = tdModel.FrontThicknessResult7,
                    SmallEndDirectionInspectionResult = tdModel.SmallEndDirectionInspectionResult,
                    FacadeCurvatureResult = tdModel.FacadeCurvatureResult,
                    Result = tdModel.Result,
                    RunType = tdModel.RunType,
                    CreatedTime = DateTime.Now,
                    ModifiedTime = DateTime.Now
                };
                List<Detectiondetail> detailList = new();
                if (tdModel.detaillist.Any())
                {
                    foreach (var item in tdModel.detaillist)
                    {
                        detailList.Add(new Detectiondetail()
                        {
                            Id = Guid.NewGuid(),
                            ParentId = TDEntity.Id,
                            DetectedType = item.DetectedType,
                            DetectedTypeDisplay = item.DetectedTypeDisplay,
                            DetectedData = item.DetectedData,
                            Description = tdModel.RunType/*item.Description*/,
                            DetectedIndex = item.DetectedIndex,
                            DetectedStatus = item.DetectedStatus,
                            DetectedTime = item.DetectedTime,
                            PartCode = item.PartCode,
                            Plcip = item.Plcip,
                            CreatedTime = DateTime.Now,
                            ModifiedTime = DateTime.Now
                        });
                    }

                    FacedCamber = tdModel.detaillist.Where(p => p.DetectedType == "Cam").FirstOrDefault()?.DetectedData;
                    //backScallop2Pitch = tdModel.detaillist.Where(p => p.DetectedType == bs1).FirstOrDefault()?.DetectedData;
                    //backScallop2Diameter = tdModel.detaillist.Where(p => p.DetectedType == bd1).FirstOrDefault()?.DetectedData;
                    backScallop3Pitch = tdModel.detaillist.Where(p => p.DetectedType == bs2).FirstOrDefault()?.DetectedData;
                    backScallop3Diameter = tdModel.detaillist.Where(p => p.DetectedType == bd2).FirstOrDefault()?.DetectedData;
                    //frontScallop2Pitch = tdModel.detaillist.Where(p => p.DetectedType == fs1).FirstOrDefault()?.DetectedData;
                    //frontScallop2Diameter = tdModel.detaillist.Where(p => p.DetectedType == fd1).FirstOrDefault()?.DetectedData;
                    //frontScallop3Pitch = tdModel.detaillist.Where(p => p.DetectedType == fs2).FirstOrDefault()?.DetectedData;
                    //frontScallop3Diameter = tdModel.detaillist.Where(p => p.DetectedType == fd2).FirstOrDefault()?.DetectedData;
                    var FrontThickness = tdModel.detaillist.Where(p => p.DetectedTypeDisplay == "FCT" || p.DetectedTypeDisplay == "BCT").ToList();
                    if (FrontThickness != null && FrontThickness.Count > 0)
                    {
                        maxThickness = FrontThickness.Max(p => p.DetectedData);
                        MiniThickness = FrontThickness.Min(p => p.DetectedData);
                    }
                    FtFs = tdModel.detaillist.Where(p => p.DetectedType == "FtFS").FirstOrDefault()?.DetectedData;
                    FtLs = tdModel.detaillist.Where(p => p.DetectedType == "FtLS").FirstOrDefault()?.DetectedData;
                    BtFs = tdModel.detaillist.Where(p => p.DetectedType == "BtFS").FirstOrDefault()?.DetectedData;
                    BtLs = tdModel.detaillist.Where(p => p.DetectedType == "BtLS").FirstOrDefault()?.DetectedData;
                    FCT1 = tdModel.detaillist.Where(p => p.DetectedType == "FCT1").FirstOrDefault()?.DetectedData;
                    FCT2 = tdModel.detaillist.Where(p => p.DetectedType == "FCT2").FirstOrDefault()?.DetectedData;
                    FCT3 = tdModel.detaillist.Where(p => p.DetectedType == "FCT3").FirstOrDefault()?.DetectedData;
                    FCT4 = tdModel.detaillist.Where(p => p.DetectedType == "FCT4").FirstOrDefault()?.DetectedData;
                    FCT5 = tdModel.detaillist.Where(p => p.DetectedType == "FCT5").FirstOrDefault()?.DetectedData;
                    FCT6 = tdModel.detaillist.Where(p => p.DetectedType == "FCT6").FirstOrDefault()?.DetectedData;
                    FCT7 = tdModel.detaillist.Where(p => p.DetectedType == "FCT7").FirstOrDefault()?.DetectedData;
                    BCT1 = tdModel.detaillist.Where(p => p.DetectedType == "BCT1").FirstOrDefault()?.DetectedData;
                    BCT2 = tdModel.detaillist.Where(p => p.DetectedType == "BCT2").FirstOrDefault()?.DetectedData;
                    BCT3 = tdModel.detaillist.Where(p => p.DetectedType == "BCT3").FirstOrDefault()?.DetectedData;
                    BCT4 = tdModel.detaillist.Where(p => p.DetectedType == "BCT4").FirstOrDefault()?.DetectedData;
                    BCT5 = tdModel.detaillist.Where(p => p.DetectedType == "BCT5").FirstOrDefault()?.DetectedData;
                    BCT6 = tdModel.detaillist.Where(p => p.DetectedType == "BCT6").FirstOrDefault()?.DetectedData;
                    BCT7 = tdModel.detaillist.Where(p => p.DetectedType == "BCT7").FirstOrDefault()?.DetectedData;
                }
                //TDEntity.CrsmallEndDistanceResult = ForeachIndicatorToleranceZone("FtFS", (float)FtFs, listIndicator);
                //TDEntity.CrlargeEndDistanceResult = ForeachIndicatorToleranceZone("FtLS", (float)FtLs, listIndicator);
                //TDEntity.Crfront1WaveDistanceResult = ForeachIndicatorToleranceZone("BtFS", (float)BtFs, listIndicator);
                //TDEntity.Crfront64WaveDistanceResult = ForeachIndicatorToleranceZone("BtLS", (float)BtLs, listIndicator);
                //TDEntity.FrontThicknessResult1 = ForeachIndicatorToleranceZone("FCT1",(float)FCT1, listIndicator);
                //TDEntity.FrontThicknessResult2 = ForeachIndicatorToleranceZone("FCT2", (float)FCT2, listIndicator);
                //TDEntity.FrontThicknessResult3 = ForeachIndicatorToleranceZone("FCT3", (float)FCT3, listIndicator);
                //TDEntity.FrontThicknessResult4 = ForeachIndicatorToleranceZone("FCT4", (float)FCT4, listIndicator);
                //TDEntity.FrontThicknessResult5 = ForeachIndicatorToleranceZone("FCT5", (float)FCT5, listIndicator);
                //TDEntity.FrontThicknessResult6 = ForeachIndicatorToleranceZone("FCT6", (float)FCT6, listIndicator);
                //TDEntity.FrontThicknessResult7 = ForeachIndicatorToleranceZone("FCT7", (float)FCT7, listIndicator);
                //TDEntity.BackThicknessResult1 = ForeachIndicatorToleranceZone("BCT1", (float)BCT1, listIndicator);
                //TDEntity.BackThicknessResult2 = ForeachIndicatorToleranceZone("BCT2", (float)BCT2, listIndicator);
                //TDEntity.BackThicknessResult3 = ForeachIndicatorToleranceZone("BCT3", (float)BCT3, listIndicator);
                //TDEntity.BackThicknessResult4 = ForeachIndicatorToleranceZone("BCT4", (float)BCT4, listIndicator);
                //TDEntity.BackThicknessResult5 = ForeachIndicatorToleranceZone("BCT5", (float)BCT5, listIndicator);
                //TDEntity.BackThicknessResult6 = ForeachIndicatorToleranceZone("BCT6", (float)BCT6, listIndicator);
                //TDEntity.BackThicknessResult7 = ForeachIndicatorToleranceZone("BCT7", (float)BCT7, listIndicator);

                if (TDEntity.FacadeCurvatureResult == true)
                {
                    FinalJudge = "OK";
                }
                else
                {
                    FinalJudge = "NG";
                }
                if (TDEntity.CrsmallEndDistanceResult == true && TDEntity.CrlargeEndDistanceResult == true && TDEntity.Crfront1WaveDistanceResult == true && TDEntity.Crfront64WaveDistanceResult == true)
                {
                    FSTotalJudge = "OK";
                }

                Op30coredata op30CoreData = new Op30coredata()
                {
                    SerialNumber = tdModel.PartCode,
                    TestTime = DateTime.Now,
                    Passageway = tdModel.RunType,
                    FacadeCamber = FacedCamber,
                    CamberJudge = tdModel.FacadeCurvatureResult == true ? "OK" : "NG",
                    BackScallop3Pitch = backScallop3Pitch,
                    BackScallop3Diameter = backScallop3Diameter,
                    MaxThickness = maxThickness,
                    MaxThicknessJudge = TDEntity.FrontThicknessResult2 == true ? "OK" : "NG",
                    MiniThickness = MiniThickness,
                    MiniThicknessJudge = TDEntity.FrontThicknessResult3 == true ? "OK" : "NG",
                    FinalJudge = tdModel.Result == true ? "OK" : "NG",
                    thicknessJudge = TDEntity.FrontThicknessResult1 == true ? "OK" : "NG",
                    Sc01 = FtFs,
                    Sc01Judge = TDEntity.CrsmallEndDistanceResult == true ? "OK" : "NG",
                    Sc02 = FtLs,
                    Sc02Judge = TDEntity.CrlargeEndDistanceResult == true ? "OK" : "NG",
                    Sc03 = BtFs,
                    Sc03Judge = TDEntity.Crfront1WaveDistanceResult == true ? "OK" : "NG",
                    Sc04 = BtLs,
                    Sc04Judge = TDEntity.Crfront64WaveDistanceResult == true ? "OK" : "NG",
                    SedJudge = string.IsNullOrEmpty(FSTotalJudge) ? "NG" : FSTotalJudge
                };
                _logService.LogOp30("客户核心保存参数" + JsonConvert.SerializeObject(op30CoreData) + "\r\n");
                return _thicknessDetectionRepository.Add(TDEntity, detailList, op30CoreData);
            }
            catch (Exception ex)
            {
                _logService.LogOp30("保存失败：" + ex.ToString(), LogLevel.Error);
                return MessageInfoUtils.Fail(ex.Message);

            }
        }

        /// <summary>
        /// 遍历公差带
        /// </summary>
        /// <param name="item"></param>
        /// <param name="indicatorToleranceZonesList">公差带配置JSON</param>
        /// <returns></returns>
        private bool ForeachIndicatorToleranceZone(string key, float value, IEnumerable<IndicatorToleranceZoneModel> indicatorToleranceZonesList)
        {
            bool indicator = true;
            var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(key));
            var result = JudgeIndicatorToleranceZone(value, indicatorInfo);
            if (result == false)
            {
                indicator = result;
            }
            return indicator;
        }

        /// <summary>
        /// 判断是否在公差带范围内
        /// </summary>
        /// <param name="values">基准值</param>
        /// <param name="indicatorToleranceZones">公差带</param>
        /// <returns>True表示在公差范围内</returns>
        private bool JudgeIndicatorToleranceZone(float value, IndicatorToleranceZoneModel indicatorToleranceZones)
        {
            bool indicator = true;
            if (value == null || indicatorToleranceZones == null)
            {
                //return indicator;
                return false;
            }
            float? DetectedData = value;
            if (indicatorToleranceZones.ContentType == "0") //正负范围
            {
                if ((indicatorToleranceZones.Indicator + indicatorToleranceZones.ToleranceZone) < DetectedData
                    || (indicatorToleranceZones.Indicator - indicatorToleranceZones.ToleranceZone) > DetectedData)
                {
                    indicator = false;
                }
            }
            else if (indicatorToleranceZones.ContentType == "1") //最大值
            {
                if (indicatorToleranceZones.ToleranceZone + indicatorToleranceZones.Indicator < DetectedData)
                {
                    indicator = false;
                }
            }
            else if (indicatorToleranceZones.ContentType == "2") //最小值
            {
                if (indicatorToleranceZones.Indicator - indicatorToleranceZones.ToleranceZone > DetectedData)
                {
                    indicator = false;
                }
            }

            return indicator;
        }


        /// <summary>
        /// 读取配置文件
        /// </summary>
        /// <returns></returns>
        public List<IndicatorToleranceZoneModel> IndicatortolerancezoneJsonLoad()
        {
            string filePath = "Indicatortolerancezone.json";
            string text = File.ReadAllText(filePath);
            return JsonConvert.DeserializeObject<List<IndicatorToleranceZoneModel>>(text);
        }

        public ParaShowSetModel ParaJsonLoad()
        {
            string filePath = "ParaSet.json";
            string text = File.ReadAllText(filePath);
            return JsonConvert.DeserializeObject<ParaShowSetModel>(text);
        }

        /// <summary>
        /// 查找今天的性能率
        /// </summary>
        /// <returns></returns>
        public ResultReturn SelectPerformanceRecord()
        {
            return _thicknessDetectionRepository.SelectPerformanceRecord();
        }

        /// <summary>
        /// 添加性能率记录
        /// </summary>
        /// <param name="record"></param>
        /// <returns></returns>
        public ResultReturn AddPerformanceRecord(PerformanceRecord record)
        {
            return _thicknessDetectionRepository.AddPerformanceRecord(record);
        }
        /// <summary>
        /// 保存基恩士激光扫描仪
        /// </summary>
        /// <param name="tdModel"></param>
        /// <returns></returns>
        public ResultReturn KeyenceAdd(List<DetectionDetail> keyenceModel)
        {
            try
            {
                _logService.LogOp30("点激光数据保存：" + JsonConvert.SerializeObject(keyenceModel) + "\r\n");
                List<Detectiondetail> detailList = new();
                if (keyenceModel != null && keyenceModel.Any())
                {
                    var detection = _thicknessDetectionRepository.GetByID(keyenceModel.First().ParentId);
                    foreach (var item in keyenceModel)
                    {
                        detailList.Add(new Detectiondetail()
                        {
                            Id = Guid.NewGuid(),
                            ParentId = item.ParentId.Value,
                            CreatedTime = DateTime.Now,
                            DetectedIndex = item.DetectedIndex,
                            DetectedStatus = item.DetectedStatus,
                            DetectedTime = item.DetectedTime,
                            DetectedType = item.DetectedType,
                            DetectedTypeDisplay = item.DetectedTypeDisplay,
                            PartCode = detection?.PartCode ?? "",
                            Description = item.Description,
                            DetectedData = item.DetectedData,
                            Plcip = item.Plcip
                        });
                    }
                    return _thicknessDetectionRepository.KeyenceAdd(detailList);
                }
                return MessageInfoUtils.Success();
            }
            catch (Exception ex)
            {
                _logService.LogOp30("点激光数据保存失败：" + ex.ToString(), LogLevel.Error);
                return MessageInfoUtils.Fail(ex.Message);
            }

        }

        /// <summary>
        /// 导出3D线扫数据
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public ResultReturn Export3DKeyenceList(TotalReq req)
        {
            var query = _thicknessDetectionRepository.Export3DKeyenceList(req);
            List<ReturnKeyValueList> returnKeyValueLists = ModelUtils.ReturnTransfor(query);
            FileOperation fileOperation = new();
            return fileOperation.FileExport(returnKeyValueLists, "检测记录", "Export_" + DateTime.Now.ToString("yyyyMMddHHmms"));
        }
    }
}
